package com.skyline.meteor.converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;

import com.skyline.meteor.exception.ConvertFailedException;
import com.skyline.meteor.multipart.MultipartFile;
import com.skyline.meteor.multipart.MultipartHttpServletRequest;
import com.skyline.meteor.utils.ConvertUtils;

/**
 * 类型转换器，用于将request请求中的参数、uriTemplateVariables中的变量值转换为简单的基本对象。
 * 基本对象包括：基本类型、基本类型的封装类
 * 、HttpServletRequest、HttpServletResponse、MultipartFile、BigDecimal
 * 、枚举类型、URI、URL等
 * 
 * @author wuqh
 * 
 */
public class SimpleTypeConverter implements Converter {
	private final Object NOT_HTTP_VALUE = new Object();
	private final Object NOT_DATE_VALUE = new Object();
	
	private final SimpleDateFormat dateFormat;

	
	/**
	 * 构造函数
	 * 
	 * @param pattern
	 *            解析的日期格式（如yyyy-MM-dd）
	 */
	public SimpleTypeConverter(String pattern) {
		if (StringUtils.isNotBlank(pattern)) {
			dateFormat = new SimpleDateFormat(pattern);
		} else {
			dateFormat = null;
		}
	}

	@Override
	public Object convertValue(ContextProvider provider, String propertyName, Class<?> toType) {
		Object httpValue = convertHttpValue(provider, propertyName, toType);
		
		if(NOT_HTTP_VALUE != httpValue) {
			return httpValue;
		}

		Map<String, String[]> parameterValues = provider.getRequestParameters();

		String value = getSingleParameter(propertyName, parameterValues);
		if(value == null) {
			return null;
		}

		Object dateValue = getDateValue(toType, value);
		if(dateValue != NOT_DATE_VALUE) {
			return dateValue;
		}

		return ConvertUtils.convertValue(value, toType);

	}

	private Object getDateValue(Class<?> toType, String value) {
		if (toType.equals(Date.class) && dateFormat != null) {
			try {
				return dateFormat.parse(value);
			} catch (ParseException e) {
				throw new ConvertFailedException("解析日期格式失败", e);
			}
		}
		
		return NOT_DATE_VALUE;
	}

	private String getSingleParameter(String propertyName, Map<String, String[]> parameterValues) {
		if (parameterValues == null) {
			return null;
		}

		String[] values = parameterValues.get(propertyName);
		if (values == null || values.length == 0) {
			return null;
		}
		
		return values[0];
	}

	private Object convertHttpValue(ContextProvider provider, String propertyName, Class<?> toType) {
		if (toType.equals(HttpServletRequest.class) || toType.equals(MultipartHttpServletRequest.class)) {
			return provider.getRequest();
		}
		if (toType.equals(HttpServletResponse.class)) {
			return provider.getResponse();
		}

		if (toType.equals(HttpSession.class)) {
			return provider.getSession();
		}

		if (toType.equals(MultipartFile.class)) {
			Map<String, List<MultipartFile>> multipartFiles = provider.getMultipartFiles();
			return (multipartFiles == null ? null : multipartFiles.get(propertyName).get(0));
		}
		
		return NOT_HTTP_VALUE;
	}

}
